#include<iostream>
#include "work1.h"
#include "class.h"
#include "gclass.h"
using namespace std;

int Grammar::FinishGrammar()
{
	int i,j;
	AddRule("E","TG");
	AddRule("G","+TG");
	AddRule("G","-TG");
	AddRule("G","%");
	AddRule("T","FS");
	AddRule("S","*FS");
	AddRule("S","/FS");
	AddRule("S","%");
	AddRule("F","(E)");
	AddRule("F","i");
	SetTerList("+ i - * / ( )");
	SetNTerList();
	terminatorList.Print();
	nonTerminatorList.Print();
	for(i=0;i<nonTerminatorList.indexEnd-1;i++)
		for(j=0;j<nonTerminatorList.ruleNum[i];j++)
			nonTerminatorList.pRule[i][j]->Print();
	SetFirst();
	//SetFollow();
	return 0;
}

void Grammar::AddRule(char *l,char *r)
{
	if(ruleNum<10)
	{
		rule[ruleNum].SetRule(l,r);
		ruleNum++;
	}
}

void Grammar::SetNTerList()
{
	int i,j,n;
	for(i=0;i<ruleNum;i++)
	{
		buffer[0]=rule[i].left[0];
		buffer[1]=0;
		if(!nonTerminatorList.SearchForWord())
			nonTerminatorList.AddWord(buffer);
		for(j=0;rule[i].right[j]!=0;j++)
		{
			buffer[0]=rule[i].right[j];
			buffer[1]=0;
			if((!nonTerminatorList.SearchForWord())&&(!terminatorList.SearchForWord())&&(buffer[0]!='%'))
			{
				nonTerminatorList.AddWord(buffer);
			}
		}
	}
	for(j=1;j<nonTerminatorList.indexEnd;j++)
	{
		for(i=0;i<ruleNum;i++)
		{
			nonTerminatorList.At(j);
			if(rule[i].left[0]==buffer[0])
			{
				n=nonTerminatorList.ruleNum[j-1];
				nonTerminatorList.pRule[j-1][n]=&rule[i];
				nonTerminatorList.ruleNum[j-1]++;
			}
		}
	}
}

void Grammar::SetSelect()
{
	int num;
	bool empty;
	for(int i=0;i<ruleNum;i++)
	{
		empty=false;
		for(int j=0;j<strlen(rule[i].right);j++)
		{
			buffer[0]=rule[i].right[j];
			buffer[1]='\0';
			if(terminatorList.SearchForWord()!=0)
			{
				rule[i].SelectList.AddWord(buffer);
				empty=false;
				break;
			}
			else if(nonTerminatorList.SearchForWord()!=0)
			{				
				num=nonTerminatorList.SearchForWord();
				buffer[0]='%';
				buffer[1]='\0';
				if(nonTerminatorList.FirstList[num-1].SearchForWord()!=0)
				{
					rule[i].SelectList.Merge(nonTerminatorList.FirstList[num-1]);
					empty=true;
					buffer[0]='%';
					buffer[1]='\0';
					rule[i].SelectList.Delete(rule[i].SelectList.SearchForWord());
				}
				else
				{
					rule[i].SelectList.Merge(nonTerminatorList.FirstList[num-1]);
					empty=false;
					break;
				}					
			}
			else
			{
				empty=true;
			}
		}
		if(empty==true)
		{
			buffer[0]=rule[i].left[0];
			buffer[1]='\0';
			rule[i].SelectList.Merge(nonTerminatorList.FollowList[nonTerminatorList.SearchForWord()-1]);			
		}
	}
}

int Grammar::CreateRelTable()
{
	int num,i;
	for(int j=0;j<terminatorList.GetSum();j++)
	{
		for(int k=0;k<ruleNum;k++)
		{
			terminatorList.At(j+1);
			buffer[1]='\0';
			if(rule[k].SelectList.SearchForWord()!=0)
			{
				buffer[0]=rule[k].left[0];
				buffer[1]='\0';
				num=nonTerminatorList.SearchForWord();
				for(i=0;rule[k].right[i]!='\0';i++)
				{
					if(RelationTable[num-1][j][i]=='\0')
					{
						RelationTable[num-1][j][i]=rule[k].right[i];
					}
					else
					{
						return 0;
					}
				}
				RelationTable[num-1][j][i]='\0';
			}
		}
	}
	return 1;
}
